{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# List Comprehensions [demonstration]\n",
    "One of Python's most \"Pythonic\" features is the **list comprehension**. It's a way of creating a list in a compact and, once you get used to them, readable way. See the demonstrations below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# The preferred 'pythonic' way to create a list\n",
    "numbers_0_to_9 = [x for x in range(10)]\n",
    "print(\"Numbers 0 to 9\", numbers_0_to_9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# The above is equivalent to the following just more compact:\n",
    "numbers_0_to_9 = []\n",
    "for x in range(10):\n",
    "    numbers_0_to_9.append(x)\n",
    "print(\"Numbers 0 to 9\", numbers_0_to_9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# You can also choose to do computation / flow control when generating\n",
    "# lists\n",
    "squares = [x * x for x in range(10)]\n",
    "print(\"Squares       \", squares)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# note - this example uses the \"modulo\" operator\n",
    "odds = [x for x in range(10) if x % 2 == 1]\n",
    "print(\"Odds          \", odds)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Advanced List Comprehensions [optional]\n",
    "If you're already an advanced programmer, you may be interested in some of these more advanced list comprehensions. They're one of the things that experienced Python users learn to love about Python.\n",
    "\n",
    "This example also uses a data type called a namedtuple which is similar to a `struct` data type in other languages."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import the module collections and be able to access namedtuple\n",
    "# wihtout having to write collections.namedtuple each time.\n",
    "from collections import namedtuple\n",
    "# Create a tuple of class 'Person'\n",
    "Person = namedtuple(\"Person\", [\"name\", \"age\", \"gender\"])\n",
    "\n",
    "# Build a list of people by using Person\n",
    "people = [\n",
    "    Person(\"Andy\", 30, \"m\"),\n",
    "    Person(\"Ping\", 1, \"m\"), \n",
    "    Person(\"Tina\", 32, \"f\"),\n",
    "    Person(\"Abby\", 14, \"f\"),\n",
    "    Person(\"Adah\", 13, \"f\"),\n",
    "    Person(\"Sebastian\", 42, \"m\"),\n",
    "    Person(\"Carol\" , 68, \"f\"),\n",
    "]\n",
    "\n",
    "# first, let's show how this namedtuple works.\n",
    "# Get the first entry in the list (which is Andy from above)\n",
    "andy = people[0]\n",
    "\n",
    "# From here, you can access andy like it was a class with attributes\n",
    "# name, age, and gender (as seeon from the namedtuple)\n",
    "print(\"name:  \", andy.name)\n",
    "print(\"age:   \", andy.age)\n",
    "print(\"gender:\", andy.gender)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# now let's show what we can do with a list comprehension\n",
    "male_names = [person.name for person in people if person.gender==\"m\"]\n",
    "print(\"Male names:\", male_names)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a list of names where there age \n",
    "teen_names = [p.name for p in people if 13 <= p.age <= 18 ]\n",
    "print(\"Teen names:\", teen_names)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
